package xyz.lisys.boot.config;


import org.springframework.boot.actuate.autoconfigure.endpoint.web.CorsEndpointProperties;
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementPortType;
import org.springframework.boot.actuate.endpoint.ExposableEndpoint;
import org.springframework.boot.actuate.endpoint.web.*;
import org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpointsSupplier;
import org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpointsSupplier;
import org.springframework.boot.actuate.endpoint.web.servlet.WebMvcEndpointHandlerMapping;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

@Configuration
public class ActuatorConfigurer {

    // https://gitee.com/xiaoym/knife4j/issues/I4JT89
    // 解决actuator与swagger2冲突

    @Bean
    public WebMvcEndpointHandlerMapping webMvcEndpointHandlerMapping(
            WebEndpointsSupplier wes, ServletEndpointsSupplier ses, ControllerEndpointsSupplier ces,
            CorsEndpointProperties cep, WebEndpointProperties wep, EndpointMediaTypes emt, Environment env
    ) {
        // WebEndpointsSupplier：用于获取Web端点的供应器
        // ServletEndpointsSupplier：用于获取Servlet端点的供应器
        // ControllerEndpointsSupplier：用于获取Controller端点的供应器

        // CorsEndpointProperties：用于设置跨域配置
        // WebEndpointProperties：用于设置Web端点的属性
        // EndpointMediaTypes：用于指定要支持的媒体类型
        // Environment：用于获取环境信息

        List<ExposableEndpoint<?>> allEndpoints = new ArrayList<>();
        Collection<ExposableWebEndpoint> webEndpoints = wes.getEndpoints();

        allEndpoints.addAll(webEndpoints);
        allEndpoints.addAll(ses.getEndpoints());
        allEndpoints.addAll(ces.getEndpoints());

        String basePath = wep.getBasePath();
        EndpointMapping endpointMapping = new EndpointMapping(basePath);
        boolean shouldRegisterLinksMapping = wep.getDiscovery().isEnabled() &&
                (StringUtils.hasText(basePath) || ManagementPortType.get(env).equals(ManagementPortType.DIFFERENT));

        return new WebMvcEndpointHandlerMapping(
                endpointMapping, webEndpoints, emt, cep.toCorsConfiguration(),
                new EndpointLinksResolver(allEndpoints, basePath),
                shouldRegisterLinksMapping, null
        );
    }
}
